#load relevant libraries
library(dplyr)

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(ggplot2)
#Import data into a new data frame
MasterData<-read.csv("~/downloads/FRE1120 Data Summary - RAW.csv")
#Removing students that were not required to do the LS exercises
MasterData<-MasterData[MasterData$LS.Required=="y",]
#Removing the few students with linguistic background different than English, Spnaish, or Creole due to very low numbers
MasterData<-MasterData[MasterData$Linguistic.Background %in% c("English","Creole","Spanish"),]
#Creating the calculated fields of Per_aware and Per_correct
MasterData <- MasterData %>% mutate(Per_correct = Correct...aware+Correct...unaware)
MasterData <- MasterData %>% mutate(Per_aware = Correct...aware+Incorrect...aware)
#eliminating redundant columns
MasterData<- select(MasterData, "ID..","Sex","Linguistic.Background","Final.Grade","Incorrect...unaware","Per_correct","Per_aware","Time.Spent..HW.","Time.Spent..Pronunciation.Practice.","Time.Spent..LearnSmart.","Total.HW...Correct","Total.LS...Complete",)
#Changing column names
names(MasterData) <- c("ID","Sex","Language","Final_grade","IU","Per_correct","Per_aware","Time_hw","Time_pron","Time_LS","Per_correct_hw","Per_complete_LS")
#Examine scatter plots for different variable combination pairs
#Creating scatter plots for all pairs
pairs(MasterData)

#Time spent on Connect homework, Percentage of correct homework responses
ggplot(MasterData, aes(Time_hw,Per_correct_hw))+ geom_point() + stat_sum(aes(group = 1))

#Time spent on Connect homework, Time spent on LearnSmart adaptive activities
ggplot(MasterData, aes(Time_hw,Time_LS))+ geom_point() + stat_sum(aes(group = 1))

#Percentage of correct homework responses, Final course grade
ggplot(MasterData, aes(Per_correct_hw,Final_grade))+ geom_point() + stat_sum(aes(group = 1))

#Percentage of correct LearnSmart responses, Percentage of awareness of correct/incorrect responses
ggplot(MasterData, aes(Per_correct,Per_aware))+ geom_point() + stat_sum(aes(group = 1))

#Percentage of completion of assigned LearnSmart activities, Final course grade
ggplot(MasterData, aes(Per_complete_LS,Final_grade))+ geom_point() + stat_sum(aes(group = 1))

#Percentage of completion of assigned LearnSmart activities, Percentage of incorrect and unaware LearnSmart responses
ggplot(MasterData, aes(Per_complete_LS,IU))+ geom_point() + stat_sum(aes(group = 1))

#Time spent on LearnSmart adaptive activities, Final course grade
ggplot(MasterData, aes(Time_LS,Final_grade))+ geom_point() + stat_sum(aes(group = 1))

#Percentage of incorrect and unaware LearnSmart responses, Final course grade
ggplot(MasterData, aes(IU,Final_grade))+ geom_point() + stat_sum(aes(group = 1))

#Percentage of incorrect and unaware LearnSmart responses, Time spent on LearnSmart adaptive activities
ggplot(MasterData, aes(IU,Time_LS))+ geom_point() + stat_sum(aes(group = 1))

#Percentage of incorrect and unaware LearnSmart responses, Time spent on Connect homework
ggplot(MasterData, aes(IU,Time_hw))+ geom_point() + stat_sum(aes(group = 1))

#Create new data frame for scaled data, removing non-clustering variables
ScaledData<-as.data.frame(cbind(MasterData[,1:3],scale(select(MasterData, Final_grade:Per_complete_LS))))
#Validating scaling by looking at means and standard deviations of the scaled columns
sapply(ScaledData[,4:12], mean)
    Final_grade              IU     Per_correct       Per_aware         Time_hw       Time_pron         Time_LS 
   5.843135e-17   -1.133857e-16    2.872520e-16   -4.121555e-16   -3.776554e-17    5.052708e-17    8.279565e-17 
 Per_correct_hw Per_complete_LS 
   2.015534e-16    4.870925e-18 
sapply(ScaledData[,4:12], sd)
    Final_grade              IU     Per_correct       Per_aware         Time_hw       Time_pron         Time_LS 
              1               1               1               1               1               1               1 
 Per_correct_hw Per_complete_LS 
              1               1 
#Creating the Within Group Sum of Squares function
wssplot <- function(data, nc=15, seed=1234){
  wss <- (nrow(data)-1)*sum(apply(data,2,var))
  for (i in 2:nc){
    set.seed(seed)
    wss[i] <- sum(kmeans(data, centers=i)$withinss)}
  plot(1:nc, wss, type="b", xlab="Number of Clusters",
       ylab="Within groups sum of squares")}
#Create the WSS Graph
wssplot(ScaledData[,4:12],nc=15,seed=1234)

#Create and examine several different possible cluster solutions
threeclusterkmeans<-kmeans(ScaledData[,4:12], 3, nstart=10)
threeclusterkmeans
K-means clustering with 3 clusters of sizes 15, 68, 46

Cluster means:
  Final_grade         IU Per_correct  Per_aware     Time_hw   Time_pron    Time_LS Per_correct_hw Per_complete_LS
1 -1.66048356 -0.4683417   0.4338804  0.2462526 -1.34682486 -0.38218605 -0.7236692   -2.050320950      -2.0744039
2  0.35681501 -0.5420303   0.4596331  0.5090781  0.02322455 -0.03493209 -0.2628125    0.450550769       0.2919678
3  0.01399637  0.9539823  -0.8209404 -0.8328501  0.40485007  0.17626462  0.6244845    0.002551347       0.2448315

Clustering vector:
  [1] 3 2 2 2 1 3 3 3 2 1 3 1 2 1 3 2 2 2 1 2 2 3 2 3 1 1 2 2 3 2 2 2 1 2 3 2 1 3 3 1 3 3 3 3 3 3 2 2 2 2 3 3 3 2 2 3 3 3 2 1 2
 [62] 2 3 2 2 3 2 2 1 2 2 2 2 2 3 3 3 2 2 3 2 2 2 3 2 2 3 2 1 3 3 3 2 2 1 2 2 2 3 2 2 2 3 3 2 2 2 2 2 2 3 1 3 2 2 3 3 2 2 2 2 2
[123] 3 3 3 2 2 2 3

Within cluster sum of squares by cluster:
[1] 108.0055 317.0107 294.2538
 (between_SS / total_SS =  37.6 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss" "betweenss"    "size"         "iter"        
[9] "ifault"      
fourclusterkmeans<-kmeans(ScaledData[,4:12], 4, nstart=10)
fourclusterkmeans
K-means clustering with 4 clusters of sizes 19, 15, 37, 58

Cluster means:
  Final_grade         IU Per_correct  Per_aware     Time_hw  Time_pron    Time_LS Per_correct_hw Per_complete_LS
1  -0.3507149  1.1769446  -0.9840832 -1.1188646  0.87451648  1.0314872  1.5405665     -0.1017225       0.1292924
2  -1.6964014 -0.6400324   0.4608217  0.2805430 -1.33097412 -0.3821861 -0.7669705     -1.8427475      -2.1677251
3   0.5572135 -0.7840533   0.9818083  0.8836826  0.07144945  0.2390765 -0.2894854      0.5519276       0.4797214
4   0.1981501  0.2801468  -0.4231319 -0.2697582  0.01215809 -0.3915741 -0.1216422      0.1578038       0.2122350

Clustering vector:
  [1] 1 4 4 4 2 4 4 4 2 2 4 2 3 2 1 3 3 3 2 4 3 4 4 4 2 2 4 3 1 3 3 4 2 4 1 3 2 1 1 2 1 1 1 1 1 4 3 4 3 3 4 4 4 4 3 1 4 4 4 2 3
 [62] 3 1 4 4 4 3 4 4 3 4 3 3 3 4 1 4 4 4 4 3 4 3 4 4 4 1 4 2 4 4 4 4 3 2 3 4 3 1 3 3 3 4 4 4 4 4 4 3 3 1 2 4 4 4 4 1 3 3 3 3 3
[123] 1 4 4 4 3 3 4

Within cluster sum of squares by cluster:
[1] 162.9807 111.4874 159.6486 194.7688
 (between_SS / total_SS =  45.4 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss" "betweenss"    "size"         "iter"        
[9] "ifault"      
#Assign the clusters for each observation for k=3,4 to a new dataframe
Clusters<-data.frame(ScaledData, as.factor(threeclusterkmeans$cluster), as.factor(fourclusterkmeans$cluster))
names(Clusters) <- c("ID","Sex","Language","Final_grade","IU","Per_correct","Per_aware","Time_hw","Time_pron","Time_LS","Per_correct_hw","Per_complete_LS","ClusterToThree","ClusterToFour")
#Graph the different solutions - Three Clusters.
#Shapes indicate Language Background. To change which variable is marked by shape, change the name of the variable in "shape=Language"
ggplot(Clusters, aes(Time_hw,Per_correct_hw, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(Time_hw,Time_LS, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(Per_correct_hw,Final_grade, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(Per_correct,Per_aware, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(Per_complete_LS,Final_grade, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(Per_complete_LS,IU, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(Time_LS,Final_grade, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(IU,Final_grade, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(IU,Time_LS, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(IU,Time_hw, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

#Graph the different solutions - Four Clusters.
#Shapes indicate Language Background. To change which variable is marked by shape, change the name of the variable in "shape=Language
ggplot(Clusters, aes(Time_hw,Per_correct_hw, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(Time_hw,Time_LS, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(Per_correct_hw,Final_grade, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(Per_correct,Per_aware, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(Per_complete_LS,Final_grade, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(Per_complete_LS,IU, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(Time_LS,Final_grade, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(IU,Final_grade, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(IU,Time_LS, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(IU,Time_hw, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

for (j in langs) {
    LangsCount[j,1] <- j
    for (i in 1:4){
      LangsCount[j,i] <- sum(UnscaledClusters$Language==j & UnscaledClusters$ClusterToFour==i)
}
}
invalid factor level, NA generatedinvalid factor level, NA generatedinvalid factor level, NA generatedinvalid factor level, NA generatedinvalid factor level, NA generatedinvalid factor level, NA generated
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQogIApgYGB7cn0KI2xvYWQgcmVsZXZhbnQgbGlicmFyaWVzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKCiNJbXBvcnQgZGF0YSBpbnRvIGEgbmV3IGRhdGEgZnJhbWUKTWFzdGVyRGF0YTwtcmVhZC5jc3YoIn4vZG93bmxvYWRzL0ZSRTExMjAgRGF0YSBTdW1tYXJ5IC0gUkFXLmNzdiIpCiNSZW1vdmluZyBzdHVkZW50cyB0aGF0IHdlcmUgbm90IHJlcXVpcmVkIHRvIGRvIHRoZSBMUyBleGVyY2lzZXMKTWFzdGVyRGF0YTwtTWFzdGVyRGF0YVtNYXN0ZXJEYXRhJExTLlJlcXVpcmVkPT0ieSIsXQojUmVtb3ZpbmcgdGhlIGZldyBzdHVkZW50cyB3aXRoIGxpbmd1aXN0aWMgYmFja2dyb3VuZCBkaWZmZXJlbnQgdGhhbiBFbmdsaXNoLCBTcG5haXNoLCBvciBDcmVvbGUgZHVlIHRvIHZlcnkgbG93IG51bWJlcnMKTWFzdGVyRGF0YTwtTWFzdGVyRGF0YVtNYXN0ZXJEYXRhJExpbmd1aXN0aWMuQmFja2dyb3VuZCAlaW4lIGMoIkVuZ2xpc2giLCJDcmVvbGUiLCJTcGFuaXNoIiksXQojQ3JlYXRpbmcgdGhlIGNhbGN1bGF0ZWQgZmllbGRzIG9mIFBlcl9hd2FyZSBhbmQgUGVyX2NvcnJlY3QKTWFzdGVyRGF0YSA8LSBNYXN0ZXJEYXRhICU+JSBtdXRhdGUoUGVyX2NvcnJlY3QgPSBDb3JyZWN0Li4uYXdhcmUrQ29ycmVjdC4uLnVuYXdhcmUpCk1hc3RlckRhdGEgPC0gTWFzdGVyRGF0YSAlPiUgbXV0YXRlKFBlcl9hd2FyZSA9IENvcnJlY3QuLi5hd2FyZStJbmNvcnJlY3QuLi5hd2FyZSkKI2VsaW1pbmF0aW5nIHJlZHVuZGFudCBjb2x1bW5zCk1hc3RlckRhdGE8LSBzZWxlY3QoTWFzdGVyRGF0YSwgIklELi4iLCJTZXgiLCJMaW5ndWlzdGljLkJhY2tncm91bmQiLCJGaW5hbC5HcmFkZSIsIkluY29ycmVjdC4uLnVuYXdhcmUiLCJQZXJfY29ycmVjdCIsIlBlcl9hd2FyZSIsIlRpbWUuU3BlbnQuLkhXLiIsIlRpbWUuU3BlbnQuLlByb251bmNpYXRpb24uUHJhY3RpY2UuIiwiVGltZS5TcGVudC4uTGVhcm5TbWFydC4iLCJUb3RhbC5IVy4uLkNvcnJlY3QiLCJUb3RhbC5MUy4uLkNvbXBsZXRlIiwpCiNDaGFuZ2luZyBjb2x1bW4gbmFtZXMKbmFtZXMoTWFzdGVyRGF0YSkgPC0gYygiSUQiLCJTZXgiLCJMYW5ndWFnZSIsIkZpbmFsX2dyYWRlIiwiSVUiLCJQZXJfY29ycmVjdCIsIlBlcl9hd2FyZSIsIlRpbWVfaHciLCJUaW1lX3Byb24iLCJUaW1lX0xTIiwiUGVyX2NvcnJlY3RfaHciLCJQZXJfY29tcGxldGVfTFMiKQoKYGBgCgpgYGB7cn0KI0V4YW1pbmUgc2NhdHRlciBwbG90cyBmb3IgZGlmZmVyZW50IHZhcmlhYmxlIGNvbWJpbmF0aW9uIHBhaXJzCiNDcmVhdGluZyBzY2F0dGVyIHBsb3RzIGZvciBhbGwgcGFpcnMKcGFpcnMoTWFzdGVyRGF0YSkKI1RpbWUgc3BlbnQgb24gQ29ubmVjdCBob21ld29yaywgUGVyY2VudGFnZSBvZiBjb3JyZWN0IGhvbWV3b3JrIHJlc3BvbnNlcwpnZ3Bsb3QoTWFzdGVyRGF0YSwgYWVzKFRpbWVfaHcsUGVyX2NvcnJlY3RfaHcpKSsgZ2VvbV9wb2ludCgpICsgc3RhdF9zdW0oYWVzKGdyb3VwID0gMSkpCiNUaW1lIHNwZW50IG9uIENvbm5lY3QgaG9tZXdvcmssIFRpbWUgc3BlbnQgb24gTGVhcm5TbWFydCBhZGFwdGl2ZSBhY3Rpdml0aWVzCmdncGxvdChNYXN0ZXJEYXRhLCBhZXMoVGltZV9odyxUaW1lX0xTKSkrIGdlb21fcG9pbnQoKSArIHN0YXRfc3VtKGFlcyhncm91cCA9IDEpKQojUGVyY2VudGFnZSBvZiBjb3JyZWN0IGhvbWV3b3JrIHJlc3BvbnNlcywgRmluYWwgY291cnNlIGdyYWRlCmdncGxvdChNYXN0ZXJEYXRhLCBhZXMoUGVyX2NvcnJlY3RfaHcsRmluYWxfZ3JhZGUpKSsgZ2VvbV9wb2ludCgpICsgc3RhdF9zdW0oYWVzKGdyb3VwID0gMSkpCiNQZXJjZW50YWdlIG9mIGNvcnJlY3QgTGVhcm5TbWFydCByZXNwb25zZXMsIFBlcmNlbnRhZ2Ugb2YgYXdhcmVuZXNzIG9mIGNvcnJlY3QvaW5jb3JyZWN0IHJlc3BvbnNlcwpnZ3Bsb3QoTWFzdGVyRGF0YSwgYWVzKFBlcl9jb3JyZWN0LFBlcl9hd2FyZSkpKyBnZW9tX3BvaW50KCkgKyBzdGF0X3N1bShhZXMoZ3JvdXAgPSAxKSkKI1BlcmNlbnRhZ2Ugb2YgY29tcGxldGlvbiBvZiBhc3NpZ25lZCBMZWFyblNtYXJ0IGFjdGl2aXRpZXMsIEZpbmFsIGNvdXJzZSBncmFkZQpnZ3Bsb3QoTWFzdGVyRGF0YSwgYWVzKFBlcl9jb21wbGV0ZV9MUyxGaW5hbF9ncmFkZSkpKyBnZW9tX3BvaW50KCkgKyBzdGF0X3N1bShhZXMoZ3JvdXAgPSAxKSkKI1BlcmNlbnRhZ2Ugb2YgY29tcGxldGlvbiBvZiBhc3NpZ25lZCBMZWFyblNtYXJ0IGFjdGl2aXRpZXMsIFBlcmNlbnRhZ2Ugb2YgaW5jb3JyZWN0IGFuZCB1bmF3YXJlIExlYXJuU21hcnQgcmVzcG9uc2VzCmdncGxvdChNYXN0ZXJEYXRhLCBhZXMoUGVyX2NvbXBsZXRlX0xTLElVKSkrIGdlb21fcG9pbnQoKSArIHN0YXRfc3VtKGFlcyhncm91cCA9IDEpKQojVGltZSBzcGVudCBvbiBMZWFyblNtYXJ0IGFkYXB0aXZlIGFjdGl2aXRpZXMsIEZpbmFsIGNvdXJzZSBncmFkZQpnZ3Bsb3QoTWFzdGVyRGF0YSwgYWVzKFRpbWVfTFMsRmluYWxfZ3JhZGUpKSsgZ2VvbV9wb2ludCgpICsgc3RhdF9zdW0oYWVzKGdyb3VwID0gMSkpCiNQZXJjZW50YWdlIG9mIGluY29ycmVjdCBhbmQgdW5hd2FyZSBMZWFyblNtYXJ0IHJlc3BvbnNlcywgRmluYWwgY291cnNlIGdyYWRlCmdncGxvdChNYXN0ZXJEYXRhLCBhZXMoSVUsRmluYWxfZ3JhZGUpKSsgZ2VvbV9wb2ludCgpICsgc3RhdF9zdW0oYWVzKGdyb3VwID0gMSkpCiNQZXJjZW50YWdlIG9mIGluY29ycmVjdCBhbmQgdW5hd2FyZSBMZWFyblNtYXJ0IHJlc3BvbnNlcywgVGltZSBzcGVudCBvbiBMZWFyblNtYXJ0IGFkYXB0aXZlIGFjdGl2aXRpZXMKZ2dwbG90KE1hc3RlckRhdGEsIGFlcyhJVSxUaW1lX0xTKSkrIGdlb21fcG9pbnQoKSArIHN0YXRfc3VtKGFlcyhncm91cCA9IDEpKQojUGVyY2VudGFnZSBvZiBpbmNvcnJlY3QgYW5kIHVuYXdhcmUgTGVhcm5TbWFydCByZXNwb25zZXMsIFRpbWUgc3BlbnQgb24gQ29ubmVjdCBob21ld29yawpnZ3Bsb3QoTWFzdGVyRGF0YSwgYWVzKElVLFRpbWVfaHcpKSsgZ2VvbV9wb2ludCgpICsgc3RhdF9zdW0oYWVzKGdyb3VwID0gMSkpCmBgYAoKYGBge3J9CiNDcmVhdGUgbmV3IGRhdGEgZnJhbWUgZm9yIHNjYWxlZCBkYXRhLCByZW1vdmluZyBub24tY2x1c3RlcmluZyB2YXJpYWJsZXMKU2NhbGVkRGF0YTwtYXMuZGF0YS5mcmFtZShjYmluZChNYXN0ZXJEYXRhWywxOjNdLHNjYWxlKHNlbGVjdChNYXN0ZXJEYXRhLCBGaW5hbF9ncmFkZTpQZXJfY29tcGxldGVfTFMpKSkpCiNWYWxpZGF0aW5nIHNjYWxpbmcgYnkgbG9va2luZyBhdCBtZWFucyBhbmQgc3RhbmRhcmQgZGV2aWF0aW9ucyBvZiB0aGUgc2NhbGVkIGNvbHVtbnMKc2FwcGx5KFNjYWxlZERhdGFbLDQ6MTJdLCBtZWFuKQpzYXBwbHkoU2NhbGVkRGF0YVssNDoxMl0sIHNkKQpgYGAKCmBgYHtyfQojQ3JlYXRpbmcgdGhlIFdpdGhpbiBHcm91cCBTdW0gb2YgU3F1YXJlcyBmdW5jdGlvbgp3c3NwbG90IDwtIGZ1bmN0aW9uKGRhdGEsIG5jPTE1LCBzZWVkPTEyMzQpewogIHdzcyA8LSAobnJvdyhkYXRhKS0xKSpzdW0oYXBwbHkoZGF0YSwyLHZhcikpCiAgZm9yIChpIGluIDI6bmMpewogICAgc2V0LnNlZWQoc2VlZCkKICAgIHdzc1tpXSA8LSBzdW0oa21lYW5zKGRhdGEsIGNlbnRlcnM9aSkkd2l0aGluc3MpfQogIHBsb3QoMTpuYywgd3NzLCB0eXBlPSJiIiwgeGxhYj0iTnVtYmVyIG9mIENsdXN0ZXJzIiwKICAgICAgIHlsYWI9IldpdGhpbiBncm91cHMgc3VtIG9mIHNxdWFyZXMiKX0KCiNDcmVhdGUgdGhlIFdTUyBHcmFwaAp3c3NwbG90KFNjYWxlZERhdGFbLDQ6MTJdLG5jPTE1LHNlZWQ9MTIzNCkKYGBgCmBgYHtyfQojQ3JlYXRlIGFuZCBleGFtaW5lIHNldmVyYWwgZGlmZmVyZW50IHBvc3NpYmxlIGNsdXN0ZXIgc29sdXRpb25zCnRocmVlY2x1c3RlcmttZWFuczwta21lYW5zKFNjYWxlZERhdGFbLDQ6MTJdLCAzLCBuc3RhcnQ9MTApCnRocmVlY2x1c3RlcmttZWFucwpmb3VyY2x1c3RlcmttZWFuczwta21lYW5zKFNjYWxlZERhdGFbLDQ6MTJdLCA0LCBuc3RhcnQ9MTApCmZvdXJjbHVzdGVya21lYW5zCmBgYApgYGB7cn0KI0Fzc2lnbiB0aGUgY2x1c3RlcnMgZm9yIGVhY2ggb2JzZXJ2YXRpb24gZm9yIGs9Myw0IHRvIGEgbmV3IGRhdGFmcmFtZQpDbHVzdGVyczwtZGF0YS5mcmFtZShTY2FsZWREYXRhLCBhcy5mYWN0b3IodGhyZWVjbHVzdGVya21lYW5zJGNsdXN0ZXIpLCBhcy5mYWN0b3IoZm91cmNsdXN0ZXJrbWVhbnMkY2x1c3RlcikpCm5hbWVzKENsdXN0ZXJzKSA8LSBjKCJJRCIsIlNleCIsIkxhbmd1YWdlIiwiRmluYWxfZ3JhZGUiLCJJVSIsIlBlcl9jb3JyZWN0IiwiUGVyX2F3YXJlIiwiVGltZV9odyIsIlRpbWVfcHJvbiIsIlRpbWVfTFMiLCJQZXJfY29ycmVjdF9odyIsIlBlcl9jb21wbGV0ZV9MUyIsIkNsdXN0ZXJUb1RocmVlIiwiQ2x1c3RlclRvRm91ciIpCmBgYAoKYGBge3J9CiNHcmFwaCB0aGUgZGlmZmVyZW50IHNvbHV0aW9ucyAtIFRocmVlIENsdXN0ZXJzLgojU2hhcGVzIGluZGljYXRlIExhbmd1YWdlIEJhY2tncm91bmQuIFRvIGNoYW5nZSB3aGljaCB2YXJpYWJsZSBpcyBtYXJrZWQgYnkgc2hhcGUsIGNoYW5nZSB0aGUgbmFtZSBvZiB0aGUgdmFyaWFibGUgaW4gInNoYXBlPUxhbmd1YWdlIgpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhUaW1lX2h3LFBlcl9jb3JyZWN0X2h3LCBncm91cCA9IGZhY3RvcihDbHVzdGVyVG9UaHJlZSkpKSArIGdlb21fcG9pbnQoKGFlcyhzaGFwZT1MYW5ndWFnZSwgY29sb3IgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKFRpbWVfaHcsVGltZV9MUywgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkgKyBnZW9tX3BvaW50KChhZXMoc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb1RocmVlKSkpKQpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhQZXJfY29ycmVjdF9odyxGaW5hbF9ncmFkZSwgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkgKyBnZW9tX3BvaW50KChhZXMoc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb1RocmVlKSkpKQpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhQZXJfY29ycmVjdCxQZXJfYXdhcmUsIGdyb3VwID0gZmFjdG9yKENsdXN0ZXJUb1RocmVlKSkpICsgZ2VvbV9wb2ludCgoYWVzKHNoYXBlPUxhbmd1YWdlLCBjb2xvciA9IGZhY3RvcihDbHVzdGVyVG9UaHJlZSkpKSkKZ2dwbG90KENsdXN0ZXJzLCBhZXMoUGVyX2NvbXBsZXRlX0xTLEZpbmFsX2dyYWRlLCBncm91cCA9IGZhY3RvcihDbHVzdGVyVG9UaHJlZSkpKSArIGdlb21fcG9pbnQoKGFlcyhzaGFwZT1MYW5ndWFnZSwgY29sb3IgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKFBlcl9jb21wbGV0ZV9MUyxJVSwgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkgKyBnZW9tX3BvaW50KChhZXMoc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb1RocmVlKSkpKQpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhUaW1lX0xTLEZpbmFsX2dyYWRlLCBncm91cCA9IGZhY3RvcihDbHVzdGVyVG9UaHJlZSkpKSArIGdlb21fcG9pbnQoKGFlcyhzaGFwZT1MYW5ndWFnZSwgY29sb3IgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKElVLEZpbmFsX2dyYWRlLCBncm91cCA9IGZhY3RvcihDbHVzdGVyVG9UaHJlZSkpKSArIGdlb21fcG9pbnQoKGFlcyhzaGFwZT1MYW5ndWFnZSwgY29sb3IgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKElVLFRpbWVfTFMsIGdyb3VwID0gZmFjdG9yKENsdXN0ZXJUb1RocmVlKSkpICsgZ2VvbV9wb2ludCgoYWVzKHNoYXBlPUxhbmd1YWdlLCBjb2xvciA9IGZhY3RvcihDbHVzdGVyVG9UaHJlZSkpKSkKZ2dwbG90KENsdXN0ZXJzLCBhZXMoSVUsVGltZV9odywgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkgKyBnZW9tX3BvaW50KChhZXMoc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb1RocmVlKSkpKQpgYGAKCmBgYHtyfQojR3JhcGggdGhlIGRpZmZlcmVudCBzb2x1dGlvbnMgLSBGb3VyIENsdXN0ZXJzLgojU2hhcGVzIGluZGljYXRlIExhbmd1YWdlIEJhY2tncm91bmQuIFRvIGNoYW5nZSB3aGljaCB2YXJpYWJsZSBpcyBtYXJrZWQgYnkgc2hhcGUsIGNoYW5nZSB0aGUgbmFtZSBvZiB0aGUgdmFyaWFibGUgaW4gInNoYXBlPUxhbmd1YWdlCmdncGxvdChDbHVzdGVycywgYWVzKFRpbWVfaHcsUGVyX2NvcnJlY3RfaHcsIGdyb3VwID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkgKyBnZW9tX3BvaW50KChhZXMoc2l6ZT0yLHNoYXBlPUxhbmd1YWdlLCBjb2xvciA9IGZhY3RvcihDbHVzdGVyVG9Gb3VyKSkpKQpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhUaW1lX2h3LFRpbWVfTFMsIGdyb3VwID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkgKyBnZW9tX3BvaW50KChhZXMoc2l6ZT0yLHNoYXBlPUxhbmd1YWdlLCBjb2xvciA9IGZhY3RvcihDbHVzdGVyVG9Gb3VyKSkpKQpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhQZXJfY29ycmVjdF9odyxGaW5hbF9ncmFkZSwgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvRm91cikpKSArIGdlb21fcG9pbnQoKGFlcyhzaXplPTIsc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKFBlcl9jb3JyZWN0LFBlcl9hd2FyZSwgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvRm91cikpKSArIGdlb21fcG9pbnQoKGFlcyhzaXplPTIsc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKFBlcl9jb21wbGV0ZV9MUyxGaW5hbF9ncmFkZSwgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvRm91cikpKSArIGdlb21fcG9pbnQoKGFlcyhzaXplPTIsc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKFBlcl9jb21wbGV0ZV9MUyxJVSwgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvRm91cikpKSArIGdlb21fcG9pbnQoKGFlcyhzaXplPTIsc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKFRpbWVfTFMsRmluYWxfZ3JhZGUsIGdyb3VwID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkgKyBnZW9tX3BvaW50KChhZXMoc2l6ZT0yLHNoYXBlPUxhbmd1YWdlLCBjb2xvciA9IGZhY3RvcihDbHVzdGVyVG9Gb3VyKSkpKQpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhJVSxGaW5hbF9ncmFkZSwgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvRm91cikpKSArIGdlb21fcG9pbnQoKGFlcyhzaXplPTIsc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKElVLFRpbWVfTFMsIGdyb3VwID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkgKyBnZW9tX3BvaW50KChhZXMoc2l6ZT0yLHNoYXBlPUxhbmd1YWdlLCBjb2xvciA9IGZhY3RvcihDbHVzdGVyVG9Gb3VyKSkpKQpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhJVSxUaW1lX2h3LCBncm91cCA9IGZhY3RvcihDbHVzdGVyVG9Gb3VyKSkpICsgZ2VvbV9wb2ludCgoYWVzKHNpemU9MixzaGFwZT1MYW5ndWFnZSwgY29sb3IgPSBmYWN0b3IoQ2x1c3RlclRvRm91cikpKSkKYGBgCgoKCmBgYHtyfQojRGVzY3JpcHRpdmUgc3RhdHMgZm9yIGVhY2ggY2x1c3RlciBpbiB0aGUgNCBjbHVzdGVyIHNvbHV0aW9uClVuc2NhbGVkQ2x1c3RlcnM8LWRhdGEuZnJhbWUoTWFzdGVyRGF0YSwgYXMuZmFjdG9yKHRocmVlY2x1c3RlcmttZWFucyRjbHVzdGVyKSwgYXMuZmFjdG9yKGZvdXJjbHVzdGVya21lYW5zJGNsdXN0ZXIpKQpuYW1lcyhVbnNjYWxlZENsdXN0ZXJzKSA8LSBjKCJJRCIsIlNleCIsIkxhbmd1YWdlIiwiRmluYWxfZ3JhZGUiLCJJVSIsIlBlcl9jb3JyZWN0IiwiUGVyX2F3YXJlIiwiVGltZV9odyIsIlRpbWVfcHJvbiIsIlRpbWVfTFMiLCJQZXJfY29ycmVjdF9odyIsIlBlcl9jb21wbGV0ZV9MUyIsIkNsdXN0ZXJUb1RocmVlIiwiQ2x1c3RlclRvRm91ciIpCiNjcmVhdGluZyBsYW5ndWFnZXMgdmVjdG9yIGFuZCBsYW5ndWFnZSBjb3VudCBkZgpsYW5ncyA8LSBjKCJFbmdsaXNoIiwiU3BhbmlzaCIsIkNyZW9sZSIpCkxhbmdzQ291bnQgPC0gZGF0YS5mcmFtZShjbHVzdGVyMWNvdW50PWludGVnZXIoKSwgY2x1c3RlcjJjb3VudD1pbnRlZ2VyKCksIGNsdXN0ZXIzY291bnQ9aW50ZWdlcigpLCBjbHVzdGVyNGNvdW50PWludGVnZXIoKSwgc3RyaW5nc0FzRmFjdG9ycz1UUlVFKQoKZm9yIChqIGluIGxhbmdzKSB7CiAgICBMYW5nc0NvdW50W2osMV0gPC0gagogICAgZm9yIChpIGluIDE6NCl7CiAgICAgIExhbmdzQ291bnRbaixpXSA8LSBzdW0oVW5zY2FsZWRDbHVzdGVycyRMYW5ndWFnZT09aiAmIFVuc2NhbGVkQ2x1c3RlcnMkQ2x1c3RlclRvRm91cj09aSkKfQp9CmBgYAoKCgo=